package autoscale;

import java.util.ArrayList;
import java.util.Collection;

import Common.TraceWriter;
import cloudjunit.Config;

import com.amazonaws.services.autoscaling.AmazonAutoScaling;
import com.amazonaws.services.autoscaling.model.*;
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.model.ComparisonOperator;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmRequest;

public class CloudJUnitAutoScale
{
	static final String AMI_ID = "ami-f7fe489e";
	static final String KEYPAIR_NAME = "secondKeyPair";
	static final String SECURITY_GROUP = "AllOpen";			// TODO: change for only S3/SWF ports
	static final String INSTANCE_TYPE = "m1.small";
	
	static final String AUTOSCALE_CONF = "cloudjunitConf4";
	static final String AUTOSCALE_GROUP = "cloudjunitScaleGroup4";
	
	static final String HIGH_CPU_ALARM = "MyHighCPUAlarm";
	static final String LOW_CPU_ALARM = "MyLowCPUAlarm";


	public static void main(String[] args)
	{
		TraceWriter.trace("STARTED.");
		
		// Init stuff
		Config.initConfigWithConfigFile();
		AmazonAutoScaling aasc = Config.createAutoScaleClient();
		AmazonCloudWatch acwc = Config.createCloudWatchClient();
		
		Collection<Dimension> dimenstions = new ArrayList<Dimension>();
		dimenstions.add(new Dimension().withName("Name").withValue("AutoScalingGroupName"));
		dimenstions.add(new Dimension().withName("Value").withValue(AUTOSCALE_GROUP));
		
		//////////////////////////////
		
		TraceWriter.trace("createLaunchConfiguration");
		CreateLaunchConfigurationRequest configRequest = new CreateLaunchConfigurationRequest();
		configRequest.setImageId(AMI_ID);
		configRequest.setLaunchConfigurationName(AUTOSCALE_CONF);
		configRequest.setInstanceType(INSTANCE_TYPE);
		configRequest.setKeyName(KEYPAIR_NAME);
		Collection<String> secGroups = new ArrayList<String>();
		secGroups.add(SECURITY_GROUP);
		configRequest.setSecurityGroups(secGroups);
		aasc.createLaunchConfiguration(configRequest);
		
		TraceWriter.trace("createAutoScalingGroup");
		CreateAutoScalingGroupRequest groupRequest = new CreateAutoScalingGroupRequest();
		groupRequest.setAutoScalingGroupName(AUTOSCALE_GROUP);
		Collection<String> availZones = new ArrayList<String>();
		availZones.add("us-east-1a");
		availZones.add("us-east-1b");
		groupRequest.setAvailabilityZones(availZones);
		groupRequest.setLaunchConfigurationName(AUTOSCALE_CONF);
		groupRequest.setMinSize(2);
		groupRequest.setMaxSize(10);
		aasc.createAutoScalingGroup(groupRequest);
		
		////////////////////////////////
		
		TraceWriter.trace("putScalingPolicy UP");
		PutScalingPolicyRequest putScaleUpRequest = new PutScalingPolicyRequest();
		putScaleUpRequest.setAutoScalingGroupName(AUTOSCALE_GROUP);
		putScaleUpRequest.setPolicyName("MyScaleUpPolicy");
		putScaleUpRequest.setScalingAdjustment(1);
		putScaleUpRequest.setAdjustmentType("ChangeInCapacity");
		putScaleUpRequest.setCooldown(300);
		PutScalingPolicyResult scaleUpResult = aasc.putScalingPolicy(putScaleUpRequest);
		
		Collection<String> scaleUpActions = new ArrayList<String>();
		scaleUpActions.add(scaleUpResult.getPolicyARN());
		TraceWriter.trace("ARN: " + scaleUpResult.getPolicyARN());
		
		TraceWriter.trace("putMetricAlarm UP");
		PutMetricAlarmRequest putMetricHighRequest = new PutMetricAlarmRequest();
		putMetricHighRequest.setAlarmName(HIGH_CPU_ALARM);
		putMetricHighRequest.setAlarmActions(scaleUpActions);
		putMetricHighRequest.setMetricName("CPUUtilization");
		putMetricHighRequest.setNamespace("AWS/EC2");
		putMetricHighRequest.setStatistic("Average");
		putMetricHighRequest.setPeriod(600);
		putMetricHighRequest.setEvaluationPeriods(1);
		putMetricHighRequest.setThreshold(80.0);
		putMetricHighRequest.setComparisonOperator(ComparisonOperator.GreaterThanThreshold);
		putMetricHighRequest.setDimensions(dimenstions);
		acwc.putMetricAlarm(putMetricHighRequest);
		
		
		////////////////////////////////		
		
		TraceWriter.trace("putScalingPolicy DOWN");
		PutScalingPolicyRequest putScaleDownRequest = new PutScalingPolicyRequest();
		putScaleDownRequest.setAutoScalingGroupName(AUTOSCALE_GROUP);
		putScaleDownRequest.setPolicyName("MyScaleDownPolicy");
		putScaleDownRequest.setScalingAdjustment(-1);
		putScaleDownRequest.setAdjustmentType("ChangeInCapacity");
		putScaleDownRequest.setCooldown(300);
		PutScalingPolicyResult scaleDownResult = aasc.putScalingPolicy(putScaleDownRequest);		
		
		Collection<String> scaleDownActions = new ArrayList<String>();
		scaleDownActions.add(scaleDownResult.getPolicyARN());
		TraceWriter.trace("ARN: " + scaleDownResult.getPolicyARN());
		
		TraceWriter.trace("putMetricAlarm DOWN");
		PutMetricAlarmRequest putMetricLowRequest = new PutMetricAlarmRequest();
		putMetricLowRequest.setAlarmName(LOW_CPU_ALARM);
		putMetricLowRequest.setAlarmActions(scaleDownActions);
		putMetricLowRequest.setMetricName("CPUUtilization");
		putMetricLowRequest.setNamespace("AWS/EC2");
		putMetricLowRequest.setStatistic("Average");
		putMetricLowRequest.setPeriod(600);
		putMetricLowRequest.setEvaluationPeriods(1);
		putMetricLowRequest.setThreshold(40.0);
		putMetricLowRequest.setComparisonOperator(ComparisonOperator.LessThanThreshold);
		putMetricLowRequest.setDimensions(dimenstions);
		acwc.putMetricAlarm(putMetricLowRequest);
		
		////////////////////////////////
		
		TraceWriter.trace("FINISHED.");
		
	}

}
